﻿using System;
using System.Net;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Deployment.Application;
using System.Text.RegularExpressions;

namespace MinecraftBackupAssistant
{
    static class UpdateChecker
    {
        private static Regex regex = new Regex(@".*Minecraft Backup Assistant v(?<Version>[0-9]\.[0-9]\.[0-9]|[0-9]\.[0-9]|[0-9])");
        public static bool IsUpdating { get; private set; }
        /// <summary>
        /// Silently check for updates
        /// </summary>
        public static bool CheckForUpdates()
        {
            IsUpdating = true;
            UpdateCheckInfo info = null;

            if (!ApplicationDeployment.IsNetworkDeployed)
            { //checking if there is a new verison from the website
                WebClient wc = new WebClient();
                string s = wc.DownloadString("http://minecraftbackup.codeplex.com/");
                if (regex.Match(s).Groups["Version"].Value != Utility.CurrentVersion)
                {
					IsUpdating = false;
                    return true;
                }
            }
            else
            {
                ApplicationDeployment updateCheck = ApplicationDeployment.CurrentDeployment;

                info = updateCheck.CheckForDetailedUpdate();

                // Check if update is actually available.
                if (info.UpdateAvailable)
                {
                    IsUpdating = false;
                    return true;
                }
            }
            IsUpdating = false;
            return false;            
        }

        /// <summary>
        /// Asks the user to update
        /// </summary>
        /// <returns>Returns whether the user choosed to update, false if there was an error</returns>
        public static bool Update(bool notifyIfNoUpdate)
        {
			if (IsUpdating)
			{
                MessageBox.Show("An update is already in progress.", "Update in progress", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }
            if (CheckForUpdates())
            {
                IsUpdating = true;
                if (!ApplicationDeployment.IsNetworkDeployed)
                {
                    if (MessageBox.Show("A new version has been found. Do you want to download it?", "Update Available", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        System.Diagnostics.Process.Start("http://minecraftbackup.codeplex.com/releases/");
                        IsUpdating = false;
                        return true;
                    }
                }
                else
                {
                    UpdateCheckInfo info = null;
                    ApplicationDeployment updateCheck = ApplicationDeployment.CurrentDeployment;

                    try
                    {
                        // Get detailed information.
                        info = updateCheck.CheckForDetailedUpdate();
                    }
                    catch (DeploymentDownloadException dde)
                    {
                        MessageBox.Show("The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later.\nError: " + dde.Message);
                        IsUpdating = false;
                        return false;
                    }
                    catch (InvalidDeploymentException ide)
                    {
                        MessageBox.Show("Cannot check for a new version of the application. The ClickOnce install is corrupt. Please reinstall the application and try again.\nError: " + ide.Message);
                        IsUpdating = false;
                        return false;
                    }
                    catch (InvalidOperationException ioe)
                    {
                        MessageBox.Show("This application cannot be updated. It is likely not a ClickOnce application. Error: " + ioe.Message);
                        IsUpdating = false;
                        return false;
                    }
                    bool doUpdate = true;

                    // Check if update is required. If not, ask user if they actually want to install.
                    if (!info.IsUpdateRequired)
                    {
                        DialogResult dialogResult = MessageBox.Show("An update is available. Would you like to update the application now? (The application will update to version " + info.AvailableVersion.ToString(), "Update Available", MessageBoxButtons.OKCancel);
                        if (!(DialogResult.OK == dialogResult))
                        {
                            doUpdate = false;
                        }
                    }

                    // Perform the actual update.
                    if (doUpdate)
                    {
                        try
                        {
                            updateCheck.Update();
                            MessageBox.Show("The application has been updated, and will now restart.");
                            Application.Restart();
                            IsUpdating = false;
                            return true;
                        }
                        catch (DeploymentDownloadException dde)
                        {
                            MessageBox.Show("Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later.\nError: " + dde);
                            IsUpdating = false;
                            return false;
                        }
                    }
                }
            }
            else
            {
                if (notifyIfNoUpdate)
                {
                    MessageBox.Show("No update is currently available", "Check for updates", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    IsUpdating = false;
                    return true;
                }
            }
            IsUpdating = false;
            return false;
        }
    }
}
